package com.sgai.zero_robot.core.io;

import static com.sgai.zero_robot.core.Config.*;
import android.text.TextUtils;
import com.sgai.zero_robot.core.callback.LogCallback;
import com.sgai.zero_robot.core.callback.ReceveCallback;
import com.sgai.zero_robot.utils.LogUtil;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

public class ReadHandler {
    private final String TAG = "ReadHandler";
    private InputStream inputStream;
    private AtomicReference<LogCallback> logcallback = new AtomicReference<>();
    private Thread readThread;
    private AtomicBoolean running = new AtomicBoolean(true);
    private ReceveCallback callback;
    public ReadHandler(InputStream inputStream,ReceveCallback callback) {
        this.inputStream= inputStream;
        this.callback= callback;
        running.set(true);
        startReadThread();
    }
    /**
     * 启动读取线程
     */
    private void startReadThread() {
        LogUtil.e(TAG,"startReadThread");
        readThread = new Thread(() -> {
            byte[] buffer = new byte[1024];
            while (running.get()) {
                try {
                    int len = inputStream.read(buffer);
                    if (len > 0) {
                        byte[] recv = new byte[len];
                        System.arraycopy(buffer, 0, recv, 0, len);
                        receiveMessage(recv);
                    }
                } catch (IOException e) {
                    LogUtil.d(TAG,"⚠️ 读取失败: " + e.getMessage());
                    LogUtil.e(e,Thread.currentThread());
                }
            }
        });
        readThread.start();
    }
    public void close() {
        LogUtil.e(TAG, "close: "+running.get() );
        if (running.get()){
            running.set(false);
            try {
                if (inputStream != null) inputStream.close();
            } catch (IOException e) {
                LogUtil.d(TAG,"🔒关闭失败 ");
                LogUtil.e(e,Thread.currentThread());
            }
        }

    }
    private StringBuffer cache = new StringBuffer();
    private void receiveMessage(byte[] recv) {
        String message = new String(recv);
        LogUtil.e(TAG,"receiveMessage "+message);
        LogCallback logCallback = logcallback.get();
        if (logCallback!=null){
            logCallback.onLog(message);
        }
        handleData(message);
    }
    private void clearCache(){
        if (cache.length()>0){
            cache.delete(0,cache.length());
        }
    }

    private void handleData(String s){
        int startIndex = s.indexOf(TAG_START);
        int endIndex = s.indexOf(TAG_END);
        //正好是开头
        if (startIndex==0){
            clearCache();
            //如果有结束符
            if (endIndex>0){
                if ((endIndex+ TAG_END.length()) == (s.length())){
                    //正好是一个完整包
                    parseString(s);
                }else{
                    //出现了粘包
                    parseString(s.substring(0,endIndex+ TAG_END.length()));
                    handleData(s.substring(endIndex+ TAG_END.length()));
                }
            }else if (endIndex<0){
                //没有结束符 丢包了
                cache.append(s);
            }
        }else if (startIndex>0){
            //如果缓存中有数据进行拼接  没有的话就认为是脏包
            if (!TextUtils.isEmpty(cache.toString())){
                cache.append(s.substring(0,startIndex));
                String message = cache.toString();
                if (message.startsWith(TAG_START)&&message.endsWith(TAG_END)){
                    //如果能拼凑出完整的数据 就直接处理
                    parseString(message);
                }
                clearCache();
            }
            //处理剩下的数据
            handleData(s.substring(startIndex));
        }else{
            //没有开始标签 看下有没有缓存 如果有缓存 那么是有开始标签的
            if (!TextUtils.isEmpty(cache.toString())){
                //如果有结束符号 那么是能组成一个完整的包的
                if (endIndex>=0){
                    cache.append(s.substring(0,endIndex+ TAG_END.length()));
                    String message = cache.toString();
                    //如果未能拼接出完整的数据 那么就是脏包
                    if (message.startsWith(TAG_START)&&message.endsWith(TAG_END)){
                        //如果能拼凑出完整的数据 就直接处理
                        parseString(message);
                    }
                    clearCache();
                    if ((endIndex+ TAG_END.length()) < (s.length()-1)){
                        handleData(s.substring(endIndex+ TAG_END.length()));
                    }
                }else{
                    //如果没有结束符号 并且缓存中有开始标签 是可以放入缓存中的
                    cache.append(s);
                }
            }else{
                //如果缓存中和目前的字符串没有开始标签  只能认为是脏数据 就不处理了
            }
        }
    }
    private void parseString(String msg){
        if (callback!=null){
            if (!TextUtils.isEmpty(msg)){
                callback.onMessage(msg.replace(TAG_START,"").replace(TAG_END,""));
            }
        }
    }

    public void setLogCallback(LogCallback logcallback) {
        this.logcallback.set(logcallback);
    }

    public void removeLogCallback() {
        logcallback.set(null);
    }
}
